/*
* ////////////////////////////////////////////////
*
* 开发者：AZPEP
* 友情链接：
*	-	B站：		零分的考卷			https://space.bilibili.com/257391258
*	-	Github：	AZPEP-BiliBili		https://github.com/AZPEP-BiliBili
*	-	Gitee：		AZPEP_BiliBili		https://gitee.com/AZPEP_BiliBili
*
* CopyRight AZPEP
*
* ////////////////////////////////////////////////
*/

#pragma once
#include "pch.h"
#include <vector>
#include <string>

/// <summary>
/// 分区基本信息
/// </summary>
typedef struct PartitionInformationW {

	/// <summary>
	/// 磁盘序号
	/// </summary>
	DWORD DiskNumber;

	/// <summary>
	/// 分区序号
	/// </summary>
	DWORD PartitionNumber;

	/// <summary>
	/// 分区样式
	/// </summary>
	PARTITION_STYLE PartitionStyle;

	/// <summary>
	/// 分区类型
	/// </summary>
	GUID PartitionType;

	/// <summary>
	/// 分区ID
	/// </summary>
	GUID PartitionId;

	/// <summary>
	/// 分区路径，如“\Device\HarddiskX\PartitionY”
	/// </summary>
	std::wstring PartitionPath;

	/// <summary>
	/// 分区卷路径
	/// </summary>
	std::wstring PartitionVolumePath;

	/// <summary>
	/// 是否挂载
	/// </summary>
	BOOL IsMounted;

	/// <summary>
	/// 盘符，若IsMounted为false则为NULL
	/// </summary>
	WCHAR Letter;
};

/// <summary>
/// 返回计算机上所有GPT分区的信息
/// </summary>
/// <param name="PartitionInformation">指向所有GPT分区的信息的结构体指针的列表</param>
/// <returns>成功返回0，PartitionInformation指向所有GPT分区的信息的结构体指针的列表；失败返回GetLastError()的错误代码，PartitionInformation为空</returns>
DWORD MountEsp_GetAllGptPartitionInformationW(
	_Out_ std::vector<PartitionInformationW*>* PartitionInformation
);

/// <summary>
/// 处理一张GPT磁盘上所有分区的基本信息
/// </summary>
/// 
/// <param name="DLIE">指向DRIVE_LAYOUT_INFORMATION_EX的指针</param>
/// <param name="PIW">指向接受PartitionInformationW*的列表的指针</param>
/// <returns>成功返回0，同时PIW指向该硬盘上所有分区的基本信息；失败返回1，磁盘为MBR磁盘或未初始化返回20000，磁盘无分区返回20001；若返回值为非零值，则PIW为空</returns>
DWORD MountEsp_ParseAGptDriveLayoutInformationEx(
	_In_ int DiskNumber,
	_In_ DRIVE_LAYOUT_INFORMATION_EX* DLIE,
	_Out_ std::vector <PartitionInformationW*>* PIW
);

/// <summary>
/// 处理一个分区的基本信息
/// </summary>
/// <param name="DiskNumber">分区所在磁盘序号</param>
/// <param name="PIE">指向PARTITION_INFORMATION_EX的指针</param>
/// <param name="PIW">指向接受PartitionInformationW的指针，请事先使用malloc与ZeroMemory分配内存</param>
/// <returns>成功返回0，同时PIW指向PartitionInformationW的指针；失败返回GetLastError()获得的错误代码，同时PIW为空残缺的结构体</returns>
DWORD MountEsp_ParseAGptPartitionInformationEx(
	_In_ DWORD DiskNumber,
	_In_ PARTITION_INFORMATION_EX* PIE,
	_Out_ PartitionInformationW* PIW
);

/// <summary>
/// 将GUID转换为std::wstring
/// </summary>
/// <param name="guid"></param>
wchar_t* GUID2StringW(GUID guid);

/// <summary>
///  获取磁盘上所有已使用的盘符
/// </summary>
/// <returns>成功GetLastError()=0，失败GetLastError()为非零值</returns>
std::vector<WCHAR> GetVolumeLetter();

/// <summary>
/// 通过卷GUID路径获取挂载的盘符。再次实现而非通过GetVolumePathNamesForVolumeName是因为GetVolumePathNamesForVolumeName存在诸多缺陷
/// </summary>
/// <param name="VolumePath">卷GUID路径</param>
/// <returns>成功返回盘符，卷未挂载返回0，获取失败返回-1，可通过GetLastError获取错误信息</returns>
WCHAR GetVolumeMountLetterW(std::wstring VolumePath);